package com.seven.first.suite.util;

import cn.hutool.core.util.NumberUtil;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * @ClassName ReflectUtil
 * @Description TODO
 * @Author seven
 * @Date 2022/5/1615:30
 * @Version 1.0
 **/
public class ReflectUtil<PO> {

    /**
     * 直接获取对象属性值
     * @param obj			对象实例
     * @param fieldName		属性名称
     * @return
     */
    public static Object getFieldValue (Object obj, String fieldName) {
        if (obj == null) return null;
        Object value = null;
        Field[] fields = obj.getClass().getDeclaredFields();
        for (int j = 0; j < fields.length; j++) {
            if (fields[j].getName().equals(fieldName)) {
                fields[j].setAccessible(true);
                // 字段值
                try {
                    value = fields[j].get(obj);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        return value;
    }

    /**
     * 通过get方法获取值
     * @param obj				实例对象
     * @param fieldName			属性名称
     * @param parameterTypes    函数的参数
     * @return
     */
    public static Object getFieldValueByMethod (Object obj, String fieldName, Class<?>... parameterTypes) {
        if (obj == null) {
            return null;
        }
        Object value = null;

        try {
            Method method = obj.getClass().getMethod(fieldGetMethodName(fieldName));
            value = method.invoke(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return value;
    }

    private static String fieldGetMethodName(String fieldName) {
        String getMethod = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        return getMethod;
    }

    /**
     * 设置值，包括key中间"."的情况
     * @param object
     * @param key
     * @param value
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void setValue(Object object, String key, Object value) {

        //用来处理多数据问题
        Object oldObj = object;

        Object obj = object;
        String attr = null;
        while (key.indexOf(".") != -1) {
            attr = key.substring(0, key.indexOf("."));
            key = key.substring(key.indexOf(".") + 1);
            if (obj instanceof Map) {
                obj = ((Map)obj).get(attr);
            } if(obj instanceof List) {
                for (Object o : (List<?>) oldObj) {
                    if (o instanceof Map) {
                        obj = ((Map)o).get(attr);
                    }else {
                        obj = getFieldValue(o, attr);
                    }
                }
            } else {
                obj = getFieldValue(obj, attr);
            }
        }

        if (obj != null) {

            if (obj instanceof Map) {
                if(oldObj instanceof List) {
                    for (Object o : (List<?>) oldObj) {
                        if (obj instanceof Map) {
                            if(attr != null) {
                                o = getFieldValue(o, attr);
                                ((Map)o).put(key, value);
                            }
                        }else {
                            setFieldValue(o, key, value);
                        }
                    }
                } else {
                    ((Map)obj).put(key, value);
                }

            } else {
                if(oldObj instanceof List) {
                    for (Object o : (List<?>) oldObj) {
                        if (obj instanceof Map) {
                            if(attr != null) {
                                o = getFieldValue(o, attr);
                                ((Map)o).put(key, value);
                            }
                        }else {
                            setFieldValue(o, key, value);
                        }
                    }
                } else {
                    setFieldValue(obj, key, value);
                }
            }
        }
    }

    /**
     * 设置值
     * @param obj
     * @param fieldName
     * @param val
     * @return
     */
    public static Object setFieldValue (Object obj, String fieldName, Object val) {
        if (obj == null) {
            return null;
        }
        Field[] fields = obj.getClass().getDeclaredFields();
        for (int j = 0; j < fields.length; j++) {
            if (fields[j].getName().equals(fieldName)) {
                fields[j].setAccessible(true);
                // 字段值
                try {
                    String type = fields[j].getType().getSimpleName();
                    //System.out.println("type : " + type);

                    if(val instanceof String) {
                        String value = val.toString();
                        if ("int".equals(type)) {
                            if (!StringUtils.isEmpty(value)) {
                                fields[j].setInt(obj, Integer.valueOf(value));
                            }
                        } else if ("long".equals(type)) {
                            if (!StringUtils.isEmpty(value)) {
                                fields[j].setLong(obj, Long.valueOf(value));
                            }
                        } else if ("double".equals(type)) {
                            if (!StringUtils.isEmpty(value)) {
                                fields[j].setDouble(obj, Double.valueOf(value));
                            }
                        } else if ("float".equals(type)) {
                            if (!StringUtils.isEmpty(value)) {
                                fields[j].setFloat(obj, Float.valueOf(value));
                            }
                        } else if ("Integer".equals(type)) {
                            if (NumberUtil.isLong(value)) {
                                fields[j].set(obj, Integer.valueOf(value));
                            } else {
                                fields[j].set(obj, null);
                            }
                        } else if ("Long".equals(type)) {
                            if (NumberUtil.isLong(value)) {
                                fields[j].set(obj, Long.valueOf(value));
                            } else {
                                fields[j].set(obj, null);
                            }
                        } else if ("Float".equals(type)) {
                            if (NumberUtil.isDouble(value)) {
                                fields[j].set(obj, Float.valueOf(value));
                            } else {
                                fields[j].set(obj, null);
                            }
                        } else if ("Double".equals(type)) {
                            if (NumberUtil.isDouble(value)) {
                                fields[j].set(obj, Double.valueOf(value));
                            } else {
                                fields[j].set(obj, null);
                            }
                        } else {
                            fields[j].set(obj, val);
                        }
                    } else {
                        fields[j].set(obj, val);
                    }

                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        return val;
    }

    /**
     * 是否存在该属性
     * @param obj  对象实例
     * @param fieldName  属性名
     * @return
     */
    public static boolean isExistField(Object obj, String fieldName) {
        boolean r = false;
        if (obj != null) {
            Field[] fields = obj.getClass().getDeclaredFields();
            for (int j = 0; j < fields.length; j++) {
                if (fields[j].getName().equals(fieldName)) {
                    r = true;
                    break;
                }
            }
        }

        return r;
    }
}
